package com.smartwork.common.sequence.bytecode;

import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

import com.smartwork.common.sequence.Sequence;
import com.smartwork.common.utils.CamelCaseUtils;
import com.smartwork.common.utils.ClassHelper;


public class SequenceCreator {
    
    private static final Map<String, Sequence> POOL_MAP = new ConcurrentHashMap<String, Sequence>(); 
   
    public static Sequence getSequence(String seqId)
    {
        if( seqId == null )
            return null;

        Sequence sequence = POOL_MAP.get(seqId);
        if( sequence == null )
        {
            sequence = newEnumSequence(seqId);
            POOL_MAP.put(seqId, sequence);
        }
        return sequence;
    }
    
    private static Sequence newEnumSequence(String seqId) {
        String cn, tn;
        
        tn = seqId.replace(".", "_") + "_seq";
        
        cn = CamelCaseUtils.toCapitalizeCamelCase(tn).replace("Seq", "Sequence");
        
        ClassLoader cl = ClassHelper.getCallerClassLoader(Sequence.class);
        ClassGenerator cg = ClassGenerator.newInstance(cl);
        cg.setSuperClass(Sequence.class);
        cg.setClassName(cn);
        StringBuilder cwt = new StringBuilder("public String getNextValue(java.sql.Connection conn)")
            .append(" throws java.sql.SQLException {");
        cwt.append("return execute(conn, \""+ tn +"\");}");
        cg.addMethod(cwt.toString());
        try
        {
            Class<?> wc = cg.toClass();
            return (Sequence)wc.newInstance();
        }
        catch(RuntimeException e)
        {
            throw e;
        }
        catch(Throwable e)
        {
            throw new RuntimeException(e.getMessage(), e);
        }
        finally
        {
            cg.release();
        }
    }
}
